package br.unifor.cct.mia.evaluate;

import java.io.File;
import java.util.Map;

import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.GenotypeConverter;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.evaluate.classification.WekaClassification;
import br.unifor.cct.mia.evolutionary.Genotype;
import br.unifor.cct.mia.evolutionary.SpeciesConstants;
import br.unifor.cct.mia.ga.Ga;

public class WekaISEvaluate implements Evaluate {

    private Map genesAnt;
    private Structure structure;
    private Database database;
    private Ga ga;
	private String[] options;
   
    public double cost(Genotype gen) {       
        double sum = 0;
       
        Integer hashCode = new Integer(gen.hashCode());
        if (!genesAnt.containsKey(hashCode)) {           

            try {
                GenotypeConverter converter = new GenotypeConverter();
                File f = converter.convert(gen,SpeciesConstants.INSTANCE_SELECTION,"temp/result.txt",structure,database,null,null);
               
                WekaClassification classificator = new WekaClassification(ga.getLearnerType(),options);
                sum = classificator.evaluate(f);
            } catch (Exception e1) {
                e1.printStackTrace();
            }        
           
            genesAnt.put(hashCode, new Double(sum));
        }
        else {
            sum = ((Double)genesAnt.get(hashCode)).doubleValue();
        }
       
        return sum;
    }

    public Object evaluate(Object value,String[] options) {
		this.options = options;             
        Object[] o = (Object[]) value;
        structure = (Structure) o[0];
        genesAnt = (Map) o[1];
        database = (Database) o[2];
        ga = (Ga)o[3];
       
        ga.sum = 0;
        ga.indexBestWorst[0] = ga.indexBestWorst[1] = 0;
      
        for(int i = 0; i < ga.configurations.getPopsize(); i++) {           
            ga.population[i].setFitness(cost((Genotype)ga.population[i]));                       
            if (ga.population[i].getFitness() > ga.population[ga.indexBestWorst[0]].getFitness())
                ga.indexBestWorst[0] = i;
            else
                if (ga.population[i].getFitness() < ga.population[ga.indexBestWorst[1]].getFitness())
                    ga.indexBestWorst[1] = i;
               
            ga.sum += ga.population[i].getFitness();
        }
       
        return ga.population;
    }
}

